Amazon RDS for PostgreSQLが読み込み性能を最大で2倍にする最適化読み込みに対応しました
Amazon RDS for PostgreSQLが読み込み性能を追加費用無しに最大で2倍にする最適化読み込み(optimized reads)に対応しました。
Amazon RDS Optimized Reads now offers up to 2X faster queries on RDS for PostgreSQL
昨年末にAmazon RDS for MySQLが読み書きの最適化に対応しましたが、今回のPostgreSQLは「読み込み」に特化した対応となっています。
インスタンスタイプとバージョンの要件を満たしていれば、デフォルト、かつ、無料でご利用いただけます。
最適化読み込みのユースケース
RDS for PostgreSQLの最適化読み込みのユースケースは、MySQLと同じです。
- 共通テーブル式(CTE)、派生テーブル、グループ化操作を含む分析クエリ
- アプリケーションの最適化されていないクエリを処理するリードレプリカ
- GROUP BYやORDER BYなどの複雑な操作で、常に適切なインデックスを使用できないオンデマンドまたはダイナミックレポートクエリ
- その他、内部テンポラリテーブルを使用するワークロード
最適化読み込みの効果
AWS公式のデータベースブログにおいて、一時ストレージが必要なワークロードを実行する際、並列度が増えるにつれて最適化読み込みが有効であることを示すベンチマークが紹介されています。
※ 図は公式ブログから
要件
以下の条件を満たすようにRDSインスタンスを作成・変更すると、最適化読み込みがデフォルトで有効になります。
- バージョン : 15.2以上、または、14.7以上、または、13.10以上
- インスタンスクラス : db.m6gd/db.r6gd/db.m5d/db.r5d
- リージョン : Beijing/Ningxia 以外
最適化読み込みの秘訣はローカルストレージ
要件のインスタンスクラス(すべてdが接尾)からわかるように、最適化読み込みに対応したRDSインスタンスは、NVMeの揮発性ローカルストレージがあります。
PostgreSQLのテーブルスペース機能を利用し、セッション関連のデータなどを rds_temp_tablespace
というスペース名でこのNVMe(/rdslocalstorage/rds_temp_tablespace
)に向けています。
この対応により、EBSよりもNVMeのIOPSのほうが高いのはもちろんのこと、Amazon EBSへの通信時のネットワークI/Oレイテンシーが改善します。 また、ストレージレイヤーレベルでEBSの全データがレプリケートされるマルチAZインスタンス環境では、NVMeにある一時データがレプリケートされなくなるため、パフォーマンスが向上します。
postgres=> show temp_tablespaces; temp_tablespaces --------------------- rds_temp_tablespace (1 row) postgres=> SELECT spcname,pg_tablespace_location(oid) FROM pg_tablespace WHERE pg_tablespace_location(oid) LIKE '%local%'; spcname | pg_tablespace_location ---------------------+-------------------------------------- rds_temp_tablespace | /rdslocalstorage/rds_temp_tablespace (1 row)
最適化読み込みが有効でない場合、これらSQLの実行結果はブランクです。
注意
最適化読み込みはローカル依存ストレージに強く依存しています。 例えば、ローカルストレージがいっぱいになると、トランザクションが失敗します。 そのため、以下の対応を行いましょう。
- クエリ失敗に備え、リトライ処理を追加
- インスタンスレベルのCloudWatch Metricsでローカルストレージを監視
- FreeLocalStorage
- ReadIOPSLocalStorage
- ReadLatencyLocalStorage
- ReadThroughputLocalStorage
- WriteIOPSLocalStorage
- WriteLatencyLocalStorage
- WriteThroughputLocalStorage
試しに、マンデルブロー集合を描くSQLを走らせたあとに、ローカルストレージを確認してみましょう。
postgres=> SELECT spcname AS "Name", pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS "size" FROM pg_catalog.pg_tablespace WHERE spcname IN ('rds_temp_tablespace'); Name | size ---------------------+------------ rds_temp_tablespace | 4096 bytes (1 row)
ローカルストレージを 4096バイト消費していますね。
RDS for PostgreSQLの最適化書き込みはいつ?
RDS for MySQLは読み書きともに最適化されているのに対して、PostgreSQLは読み込みだけです。
MySQLの場合は、Torn Write Prevention機能を導入してDouble Buffer Write を止め、最適化書き込みを実現しました。
PostgreSQLの場合、Buffered I/Oの非効率さがしばしば指摘されてきました。最近ではPostgreSQL 16に O_DIRECT
(Direct I/O)のための設定が入ったりと、書き込み改善の布石が打たれています。将来が楽しみですね。
PostgreSQL 16 dev: Add io_direct setting (developer-only).https://t.co/geVDbDYCcq pic.twitter.com/VL3U0SNTee
— Noriyoshi Shinoda (@nori_shinoda) April 8, 2023
参考
- Improving query performance for RDS for PostgreSQL with Amazon RDS Optimized Reads - Amazon Relational Database Service
- Introducing Optimized Reads for Amazon RDS for PostgreSQL | AWS Database Blog
- Amazon RDS Optimized Reads now offers up to 2X faster queries on RDS for PostgreSQL
- RDS for MySQLの最適化読み書きはどうやって実現した? #reinvent | DevelopersIO